package com.phiture.erp.basic.web.controller.admin;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import com.phiture.erp.basic.core.pojo.dto.ErpMaterialPageReqDTO;
import com.phiture.erp.basic.core.pojo.dto.ErpMaterialSaveReqDTO;
import com.phiture.erp.basic.core.pojo.vo.ErpMaterialPlanRespForBomVO;
import com.phiture.erp.basic.core.pojo.vo.ErpMaterialPlanRespVO;
import com.phiture.erp.basic.core.pojo.vo.ErpMaterialRespForBomVO;
import com.phiture.erp.basic.core.pojo.vo.ErpMaterialRespVO;
import com.phiture.erp.basic.core.service.ErpMaterialPlanService;
import com.phiture.erp.basic.core.service.ErpMaterialService;
import com.phiture.erp.basic.dal.entity.ErpMaterialDO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;

/**
 * @author YH
 * @date 2025/3/31
 */

@Tag(name = "管理后台 - ERP 物料")
@RestController
@RequestMapping("/erp/material")
@RequiredArgsConstructor
public class ErpMaterialController {
    private final ErpMaterialService materialService;

    private final ErpMaterialPlanService productPlanService;

    @PostMapping("/create")
    @Operation(summary = "创建物料")
    @PreAuthorize("@ss.hasPermission('erp:material:create')")
    public CommonResult<Long> createMaterial(@Valid @RequestBody ErpMaterialSaveReqDTO createReqDTO) {
        return success(materialService.createMaterial(createReqDTO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新物料")
    @PreAuthorize("@ss.hasPermission('erp:material:update')")
    public CommonResult<Boolean> updateMaterial(@Valid @RequestBody ErpMaterialSaveReqDTO updateReqDTO) {
        materialService.updateMaterial(updateReqDTO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除物料")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('erp:material:delete')")
    public CommonResult<Boolean> deleteMaterial(@RequestParam("id") Long id) {
        materialService.deleteMaterial(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得物料")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('erp:material:query')")
    public CommonResult<ErpMaterialRespVO> getMaterial(@RequestParam("id") Long id) {
        // 获取基本属性
        ErpMaterialDO materialDO = materialService.getMaterial(id);
        return success(BeanUtils.toBean(materialDO, ErpMaterialRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得物料分页")
    @PreAuthorize("@ss.hasPermission('erp:material:query')")
    public CommonResult<PageResult<ErpMaterialRespVO>> getMaterialPage(@Valid ErpMaterialPageReqDTO pageReqDTO) {
        return success(materialService.getMaterialPage(pageReqDTO));
    }

    @GetMapping("/simple-list")
    @Operation(summary = "获得物料精简列表", description = "只包含被开启的物料，主要用于前端的下拉选项")
    public CommonResult<List<ErpMaterialRespVO>> getMaterialSimpleList() {
        List<ErpMaterialRespVO> list = materialService.getMaterialListByStatus(CommonStatusEnum.ENABLE.getStatus());

        // 获取计划资料
        Map<Long, ErpMaterialPlanRespVO> planMap = productPlanService.getMaterialPlanRespVOMap(convertSet(list, ErpMaterialRespVO::getId));

        List<ErpMaterialRespVO> result = convertList(list, product -> new ErpMaterialRespVO().setId(product.getId())
                .setName(product.getName()).setBarCode(product.getBarCode())
                .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
                .setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
                .setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice()).setMinPrice(product.getMinPrice())
        );
        // TODO 杨欢：迁移完成补全逻辑
        return CommonResult.success(result);
    }

    @GetMapping("/simple-list-for-bom")
    @Operation(summary = "获得物料精简列表", description = "只包含被开启的物料，主要用于前端的下拉选项")
    public CommonResult<List<ErpMaterialRespForBomVO>> getMaterialSimpleListForBom() {
         List<ErpMaterialRespVO> list = materialService.getMaterialListByStatus(CommonStatusEnum.ENABLE.getStatus());

         // 获取计划资料
          Map<Long, ErpMaterialPlanRespVO> planMap = productPlanService.getMaterialPlanRespVOMap(convertSet(list, ErpMaterialRespVO::getId));

         List<ErpMaterialRespForBomVO> result = convertList(list, material -> new ErpMaterialRespForBomVO().setId(material.getId())
                 .setName(material.getName()).setBarCode(material.getBarCode()).setStandard(material.getStandard())
                 .setCategoryId(material.getCategoryId()).setCategoryName(material.getCategoryName())
                 .setUnitId(material.getUnitId()).setUnitName(material.getUnitName())
//                 .setPurchasePrice(material.getPurchasePrice()).setSalePrice(material.getSalePrice()).setMinPrice(material.getMinPrice())
                 .setPlanInfo(BeanUtils.toBean(planMap.get(material.getId()), ErpMaterialPlanRespForBomVO.class))
         );

        result = result.stream()
                .filter(item -> item.getPlanInfo() != null)
                .collect(Collectors.toList());
         // 过滤掉计划资料没有的物料
         return success(result);
//         TODO 杨欢：迁移完成补全逻辑
//        return CommonResult.success(null);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出物料 Excel")
    @PreAuthorize("@ss.hasPermission('erp:material:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportMaterialExcel(@Valid ErpMaterialPageReqDTO pageReqDTO, HttpServletResponse response) throws IOException {
        pageReqDTO.setPageSize(PageParam.PAGE_SIZE_NONE);
        PageResult<ErpMaterialRespVO> pageResult = materialService.getMaterialPage(pageReqDTO);
        // 导出 Excel
        ExcelUtils.write(response, "物料.xls", "数据", ErpMaterialRespVO.class, pageResult.getList());
    }
}
